﻿namespace MEF_Test.Module.AudioStation
{
    using System;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Windows;

    using MEF_Test.Bricks;
    using MEF_Test.Contracts;
    using MEF_Test.Module.AudioStation.Properties;

    using Microsoft.Practices.Unity;

    using Synology.AudioStationApi;

    public class AudioStationBrowsingProvider : MediaBrowsingProviderBase
    {
        private BrowserNodeViewModel<AudioStationFileHandler> _node;
        private readonly AudioStationSession _audioStationSession;



        public AudioStationBrowsingProvider(BrowserNodeViewModel<AudioStationFileHandler> node, string synoHost, int synoPort)
            : this(synoHost, synoPort)
        {
            if (node == null) throw new ArgumentNullException("node");
            if (synoHost == null) throw new ArgumentNullException("synoHost");
            _currentElement = node;
        }

        public AudioStationBrowsingProvider(string synoHost, int synoPort)
        {
            _audioStationSession = new AudioStationSession(synoHost, synoPort, (string)Settings.Default["Login"], (string)Settings.Default["Password"]);            
        }

        public void BeginLogin(BrowserNodeViewModel<AudioStationFileHandler> node)
        {
            _audioStationSession.LoginCompleted += loginCompleted;
            _audioStationSession.LoginAsync(
                (string)Settings.Default["Login"],
                (string)Settings.Default["Password"],
                new[] { node });
        }

        void loginCompleted(object sender, LoginCompletedEventArgs eventArgs)
        {
            GoToNode((BrowserNodeViewModel<AudioStationFileHandler>)eventArgs.Parameters[0]);
        }



        /// <summary>
        /// Navigates to a new node
        /// </summary>
        /// <param name="newNode">The node to navigate to</param>
        public override void GoToNode(IBrowserNodeViewModel newNode)
        {
            var audioStationBrowserNode = newNode as BrowserNodeViewModel<AudioStationFileHandler>;
            if (audioStationBrowserNode == null) throw new ArgumentException(string.Format("New node of type {0} is not of the right type : {1} expected", newNode.GetType().Name, typeof(BrowserNodeViewModel<AudioStationFileHandler>).Name));

            _node = (BrowserNodeViewModel<AudioStationFileHandler>)newNode;
            if (_node.FileHandler.CanHaveChildren)
            {                
                onCurrentChildrenChanged(this, new CurrentChildrenChangedEventArgs { Children = getChildren(newNode) });
            }

            if (_node.FileHandler.IsTrack)
            {
                throw new NotImplementedException("Track download not implemented yet.");
            }

            //throw new NotImplementedException();
        }

        public override void GoToParentNode(IBrowserNodeViewModel newNode)
        {
            makeParentNode(newNode);
            GoToNode(newNode);
        }

        private void makeParentNode(IBrowserNodeViewModel newNode)
        {
            var node = (BrowserNodeViewModel<AudioStationFileHandler>) newNode;
            node.FileHandler.ItemID = node.FileHandler.ItemPid;
            int lastSlashPosition = node.FileHandler.ItemPid.LastIndexOf('/');
            if (lastSlashPosition >= 0)
            {
                node.FileHandler.ItemPid = node.FileHandler.ItemPid.Substring(0, lastSlashPosition);                
            }
            else
            {
                node.FileHandler.ItemPid = "musiclib_root";
            }
        }

        /// <summary>
        /// Internal use only : do not call this method directly : register to the CurrentChildrenChanged instead.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        protected override ObservableCollection<IBrowserNodeViewModel> getChildren(IBrowserNodeViewModel node)
        {
            if (node == null) return new ObservableCollection<IBrowserNodeViewModel>();

            var audioStationBrowserNode = node as BrowserNodeViewModel<AudioStationFileHandler>;
            if (audioStationBrowserNode == null) throw new ArgumentException(string.Format("New node of type {0} is not of the right type : {1} expected", node.GetType().Name, typeof(BrowserNodeViewModel<AudioStationFileHandler>).Name));

            if (node.FileHandler.CanHaveChildren == false)
            {
                throw new InvalidOperationException(
                    "getCurrentChildren cannot be called when BrowserNode object's CanHaveChildren property is set to false");

                // FIXME : MAKE ACTUAL QUERY
            }

            // Call a factory that will : 
            // Build an ObservableCollection<BrowserNode> based on the Syno-Domain objects.
            var fileHandler = (AudioStationFileHandler)node.FileHandler;

                // Within the factory : 
                // Resolve unity container
            throw new NotImplementedException("replace IoC with DI.");
            var syno = IoC.Current.Resolve<IAudioStationSession>();
                // gather info to send to the AudioStationApi
                // Call the API and get Syno-Domain objects for this query
                // wrap them in the correct form inside BrowserNodes
                // return them as an ObservableCollection))
            // FIXME : remove Caption from BrowserNode<T> and use MediaHandler 
            IMediaHandler mediaHandler;
            DataTemplate dataTemplate;
            throw new NotImplementedException("Use DI to set the variables above and replace null on the line above with a real detail data template");
            return
                new ObservableCollection<IBrowserNodeViewModel>(
                    syno.Browse(fileHandler.ItemID).Select(
                        o =>
                        new BrowserNodeViewModel<AudioStationFileHandler>(
                            new AudioStationFileHandler(AudioStationAction.Browse, o), 
                            mediaHandler, 
                            dataTemplate, 
                            null, 
                            null)));
               
        }



        
    }
}